package cs2340.todolist.JUnit;

import java.util.Date;
import java.util.Random;

import android.app.Activity;
import android.test.ActivityInstrumentationTestCase2;
import cs2340.todolist.model.Location;
import cs2340.todolist.model.ToDoItem;
import cs2340.todolist.model.account_management.ToDoItemManager;
import cs2340.todolist.model.sqlite_database.ToDoItemDataSource;
import cs2340.todolist.model.sqlite_database.UserAccountDataSource;
import cs2340.todolist.splash.Splash;

/**
 * this test case tests the method insertItem() of ToDoItemDataSource
 * precondition: no other item with the same title exists in the database
 *  	userID, has to be an id existing in the database
 *  	title, can neither be blank nor null
 *  	type, has to be the one of the indices of the TYPES array in ToDoItemManager
 *  	recurType, has to be the one of the indices of the RECUR_TYPES array in ToDoItemManager
 *  	location, description, and completed can be any value
 * postcondition: item is added to the database, and the id of the item is returned
 * @author BaoTam
 *
 */
public class TestInsertItem extends ActivityInstrumentationTestCase2<Splash> {
	@SuppressWarnings("deprecation")
	public TestInsertItem() {
		super("cs2340.todolist.splash", Splash.class);
		// TODO Auto-generated constructor stub
	}


	ToDoItemDataSource itemDataSource;
	UserAccountDataSource userDataSource;
	Activity activity;
	
	public void setUp() throws Exception {
		super.setUp();
		activity = getActivity();
		itemDataSource = new ToDoItemDataSource(activity);
		userDataSource = new UserAccountDataSource(activity);
	}
	
	/**
	 * testInsert() covers equivalence partitions of the "type" and "recurType" params:
	 * 		type: invalid partition(type >= length of TYPES array, type < 0), valid partition(0 <= type < length of TYPES array), boundaries(type = 0, type = length of TYPES array)
	 * 		recurType: invalid partition(recurType >= length of RECUR_TYPES array, recurType < 0), valid partition(0 <= recurType < length of RECUR_TYPES array), boundaries(recurType = 0, recurType = length of RECUR_TYPES array)
	 *	For title, there are only 3 possibilities: blank, null, and neither, and these have also been included
	 *	testInsert() also checks for postcondition which is whether we can retrieve the item after it has been added to the database.
	 */
	public void testInsert() {
		itemDataSource.open();
		userDataSource.open();
		
		//create a fake user (will be removed later)
		long userId = userDataSource.insertUser("testGuy", "", "testUserName", "testPassword");
		
		//test insert a valid item by using a fake user
		long id0 = itemDataSource.insertItem(userId, "testTitle22", new Location("testLocation0", "Atl"), 0, new Date(), 0, "", false);
		ToDoItem toInsert = new ToDoItem(-1, "testTitle22", new Location("testLocation0", "Atl"), ToDoItemManager.TYPES[0], new Date(), ToDoItemManager.RECUR_TYPES[0], "", false);
		ToDoItem fetched = itemDataSource.getItemById(id0);
		itemDataSource.deleteItem(id0);
		
		
		//test insert an item with type index = length of the TYPES array
		long id1 = itemDataSource.insertItem(userId, "testTitle222", new Location("testLocation0", "Atl"), ToDoItemManager.TYPES.length, new Date(), 0, "", false);
		//test insert an item with type index > length of the TYPES array
		long id3 = itemDataSource.insertItem(userId, "testTitle225", new Location("testLocation0", "Atl"), ToDoItemManager.TYPES.length + 12, new Date(), 0, "", false);
		//test insert an item with 0 <= type index < length of the TYPES array
		long id4 = itemDataSource.insertItem(userId, "testTitle223", new Location("testLocation0", "Atl"), new Random().nextInt(ToDoItemManager.TYPES.length), new Date(), 0, "", false);
		itemDataSource.deleteItem(id4);
		//test insert an item with type index < 0;
		long id5 = itemDataSource.insertItem(userId, "testTitle223", new Location("testLocation0", "Atl"), -10, new Date(), 0, "", false);
		
		//test insert an item with recurType index = length of the RECUR_TYPES array
		long id6 = itemDataSource.insertItem(userId, "testTitle222", new Location("testLocation0", "Atl"),0 , new Date(), ToDoItemManager.RECUR_TYPES.length, "", false);
		//test insert an item with recurType index > length of the RECUR_TYPES array
		long id7 = itemDataSource.insertItem(userId, "testTitle225", new Location("testLocation0", "Atl"),0, new Date(), ToDoItemManager.RECUR_TYPES.length +12, "", false);
		//test insert an item with 0 <= recurType index < length of the RECUR_TYPES array
		long id8 = itemDataSource.insertItem(userId, "testTitle223", new Location("testLocation0", "Atl"),0, new Date(), new Random().nextInt(ToDoItemManager.RECUR_TYPES.length), "", false);
		itemDataSource.deleteItem(id8);
		//test insert an item with recurType index < 0;
		long id9 = itemDataSource.insertItem(userId, "testTitle223", new Location("testLocation0", "Atl"), -10, new Date(), 0, "", false);
		
		//test blank title;
		long id10 = itemDataSource.insertItem(userId, "", new Location("testLocation0", "Atl"), 0, new Date(), 0, "", false);
		//test null title;
		long id11 = itemDataSource.insertItem(userId, null, new Location("testLocation0", "Atl"), 0, new Date(), 0, "", false);
		
		userDataSource.deleteUser(userId);
		
		
		//test insert an item of a non-existent user
		long id2 = itemDataSource.insertItem(userId, "testTitle0", new Location("testLocation0", "Atl"), 0, new Date(), 0, "", false);
		
		
		itemDataSource.close();
		userDataSource.close();
		
		
		assertTrue("test insert a valid item", id0 > -1);
		assertTrue("check if valid item inserted is not null", fetched != null);
		assertTrue("check postcondition: if valid item inserted is in the database", compareItem(toInsert, fetched));
		assertEquals("test insert an item with type index = length of the TYPES array", -1, id1);
		assertEquals("test insert an item with type index > length of the TYPES array", -1, id3);
		assertTrue("test insert an item with type index > length of the TYPES array", id4 > -1);
		assertEquals("test insert an item with type index < 0",-1,id5);
		assertEquals("test insert an item with recurType index = length of the TYPES array", -1, id6);
		assertEquals("test insert an item with recurType index > length of the TYPES array", -1, id7);
		assertTrue("test insert an item with recurType index > length of the TYPES array", id8 > -1);
		assertEquals("test insert an item with recurType index < 0",-1,id9);
		assertEquals("test blank title", -1, id10);
		assertEquals("test null title", -1, id11);
		assertEquals("test insert an item of a non-existent user", -1, id2);
	}
	
	
	
	public boolean compareItem(ToDoItem item1, ToDoItem item2) {
		boolean result = false;
		if(item1.getTitle().equals(item2.getTitle())) {
			result = true;
		}
		return result;
	}
}
